﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PloobsEngine.SceneControl;
using PloobsEngine.Physics;
using PloobsEngine;
using PloobsEngine.Cameras;
using PloobsEngine.Input;
using Microsoft.Xna.Framework;
using PloobsEngine.Physics.Bepu;
using PloobsEngine.Modelo;
using PloobsEngine.Material;
using Microsoft.Xna.Framework.Graphics;
using PloobsEngine.Utils;
using PloobsEngine.Features;
using PloobsEngine.Commands;
using PloobsEngineDemo3;
using PloobsEngine.Light;
using PloobsEngine.DataAquisition;
using Microsoft.Xna.Framework.Input;

namespace Etapa1.Screens
{
    public class PerformanceScreen : SceneScreen
    {
        private BepuPhysicWorld physicWorld;
        private BrutalForceWorld mundo;
        private EngineStuff engine;        
        ICamera cam;

        public PerformanceScreen(EngineStuff es)
        {
            this.engine = es;
            physicWorld = new BepuPhysicWorld();
            mundo = new BrutalForceWorld(physicWorld);                        
            engine.Game.IsFixedTimeStep = false;            
        }
        
        public override void LoadContent(EngineStuff es)
        {            
            InputAdvanced inp = new InputAdvanced(engine);
            engine.AddComponent(inp);

            base.LoadContent(es);            

            #region Models
            {
                SimpleModel sm = new SimpleModel("..\\Content\\Model\\cenario");
                sm.LoadModelo();
                IPhysicObject pi = new TriangleMeshObject(Vector3.Zero, sm);
                NormalDeferred shader = new NormalDeferred();
                //CustomDeferred shader = new CustomDeferred(false, false, false, false);
                shader.SpecularIntensity = 0.1f;
                shader.SpecularPower = 50;
                shader.Initialize();
                IMaterial mat = new Material(shader, MaterialType.DEFERRED);
                IObject obj3 = new SimpleObject(mat, pi, sm);
                mundo.AddObject(obj3);
            }            

            #endregion            

            cam = new CameraFirstPerson(true);            
            cam.FarPlane = 3000;

            
            #region NormalLight

            #region NormalLight
            DirectionalLight ld1 = new DirectionalLight(Vector3.Left, Color.White);
            DirectionalLight ld2 = new DirectionalLight(Vector3.Right, Color.White);
            DirectionalLight ld3 = new DirectionalLight(Vector3.Backward, Color.White);
            DirectionalLight ld4 = new DirectionalLight(Vector3.Forward, Color.White);
            DirectionalLight ld5 = new DirectionalLight(Vector3.Down, Color.White);
            float li = 0.2f;
            ld1.LightIntensity = li;
            ld2.LightIntensity = li;
            ld3.LightIntensity = li;
            ld4.LightIntensity = li;
            ld5.LightIntensity = li;
            mundo.AddLight(ld1);
            mundo.AddLight(ld2);
            mundo.AddLight(ld3);
            mundo.AddLight(ld4);
            mundo.AddLight(ld5);
            #endregion

            //SleepTimer st = new SleepTimer(engine, 50, addlight);
            SleepTimer st = new SleepTimer(engine, 500, AddGeometry);            
            
                        
            #endregion

            ////Criacao de uma Tecnica
            DeferredRenderTechnic dr = new DeferredRenderTechnic(engine);
            dr.DeferredFinalCombination.SaveToTexture = false;
            dr.RestoreDepth = RestoreDepthOption.NONE;
            IRenderTechnic[] rt = new IRenderTechnic[] { dr };
            this.RenderTechnics = rt;
            mundo.AddCamera(cam);
            this.World = mundo;

            EngineStuff.DataColector.AddHandler(new GenericNumberColumFileSaver("teste", new string[] { "SMoothFPS", "ObjectNum", "PrimitiveNumberPolyCount", "NumeroLuzes" }, Keys.Space));
            EngineStuff.DataColector.AddHandler(new FileSaverDataHandler("UpdateDraw",Keys.Enter));
           
        }

        public void AddGeometry()
        {
            //EngineStuff.DataColector.Recieve(new MethodDataFormat(MethodPart.START,"AddGeometry"));            
            SimpleModel sm = new SimpleModel("..\\Content\\Model\\venus");
            sm.LoadModelo();
            IPhysicObject pi = new GhostObject(new Vector3(StaticRandom.RandomBetween(-450, 450), 1, StaticRandom.RandomBetween(-450, 450)), Matrix.Identity, Vector3.One);
            NormalDeferred shader = new NormalDeferred();
            //CustomDeferred shader = new CustomDeferred(false, false, false, false);
            shader.SpecularIntensity = 0.1f;
            shader.SpecularPower = 50;
            shader.Initialize();
            IMaterial mat = new Material(shader, MaterialType.DEFERRED);
            IObject obj3 = new SimpleObject(mat, pi, sm);
            mundo.AddObject(obj3);
            //EngineStuff.DataColector.Recieve(new MethodDataFormat(MethodPart.END, "AddGeometry"));
        }

        public void addlight()
        {
            //EngineStuff.DataColector.Recieve(new MethodDataFormat(MethodPart.START,"AddLight"));            
            PointLight pl = new PointLight(new Vector3(StaticRandom.RandomBetween(-450, 450), 10, StaticRandom.RandomBetween(-450, 450)), StaticRandom.RandomColor(), 35, 2);
            pl.UsePointLightQuadraticAttenuation = true;
            mundo.AddLight(pl);
            //EngineStuff.DataColector.Recieve(new MethodDataFormat(MethodPart.END, "AddLight"));
        }

        public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
        {
            EngineStuff.DataColector.Recieve(new GenericNumberColumDataFormat(gameTime, new double[] { EngineStuff.Clock.SmoothedFPS, mundo.ObjectsNum , mundo.Polycont, mundo.Lights.Count }));            
            base.Update(gameTime, otherScreenHasFocus, coveredByOtherScreen);            
        }

    }
}

